package com.handydata.antifraud.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.csvreader.CsvReader;
import com.handydata.antifraud.bo.dictinfo.DictInfoBeanBO;
import com.handydata.antifraud.bo.dictinfo.DictInfoReqBO;
import com.handydata.antifraud.bo.dictinfo.DictInfoResBO;
import com.handydata.antifraud.common.constant.AlarmInfoCode;
import com.handydata.antifraud.common.constant.DictInfoCode;
import com.handydata.antifraud.common.exception.DictInfoExCode;
import com.handydata.antifraud.dao.DictInfoDao;
import com.handydata.antifraud.entity.DictInfoDO;
import com.handydata.antifraud.entity.RuleInfoDo;
import com.handydata.antifraud.service.DictInfoService;
import com.handydata.common.convert.CommonBeanConvertor;
import com.handydata.common.exception.SysException;
import com.handydata.common.service.AbsService;
import com.handydata.common.util.RedisUtil;
import org.apache.commons.io.FileUtils;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;

@Service("dictInfoService")
public class DictInfoServiceImpl extends AbsService implements DictInfoService {
	
	private static final Logger logger = LoggerFactory.getLogger(DictInfoServiceImpl.class);
	
	@Autowired
	private DictInfoDao dictInfoDao;

	@Autowired
	private RedisUtil redisUtil;


	@Transactional
	@Override
	public DictInfoResBO createDictInfo(DictInfoReqBO req) throws SysException{
	    DictInfoResBO res = new DictInfoResBO();
		try {
			DictInfoDO entity = CommonBeanConvertor.convert(req, DictInfoDO.class);
			//entity.setId(UUID.randomUUID().toString().replace("-", ""));
			long status = dictInfoDao.insert(entity);
			if(status == 0) {
				res.setExCode(DictInfoExCode.SYS_NO_ENTITY_CREATED);
			} else {
				res.setExCode(DictInfoExCode.SUCCESS);
			}
 			
		} catch (Exception e) {
			logger.error("Create new entity {} get into error", req, e);
			throw new SysException(DictInfoExCode.SYS_CREATE_ENTITY_ERROR);
		}
		return res;
	}

	private void readRandomCsv1(){
		String filePath="/Users/baiyx/Desktop/AppModel_Top10Mean_190512.csv";
		Map<String, Float> data = new HashMap<String, Float>();
		CsvReader csvReader = null;
		try {
			char aa='a';
			FileInputStream inputStream=new FileInputStream(filePath);
			csvReader = new CsvReader(inputStream, Charset.defaultCharset());
			// 读表头
			csvReader.readHeaders();

			String[]headers=csvReader.getHeaders();
			// 读内容
			int count=0;
			while (csvReader.readRecord()) {
//                for(int i=0;i<headers.length;i++){
////                    if(csvReader.get(i)==null||csvReader.get(i).toString().length()<=0)
////                        data.put(headers[i],0F);
////                    else
////                        data.put(headers[i],Float.valueOf(csvReader.get(i)));
//
//                }

				String cat2=csvReader.get(0);
				String size=csvReader.get(1);
				String download=csvReader.get(2);

				DictInfoDO entity=new DictInfoDO();
				entity.setCode(cat2+"_size");
				entity.setName(size);
				entity.setType(DictInfoCode.DICT_APP_MEAN_MODEL.getCode());

				entity.setId(UUID.randomUUID().toString().replace("-", ""));
				long status = dictInfoDao.insert(entity);

				 entity=new DictInfoDO();
				entity.setCode(cat2+"_download");
				entity.setName(download);
				entity.setType(DictInfoCode.DICT_APP_MEAN_MODEL.getCode());

				entity.setId(UUID.randomUUID().toString().replace("-", ""));
				status = dictInfoDao.insert(entity);
				count++;
				System.out.println("插入"+count+"条平均值计算");
			}
			inputStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
    private void readAppNameMap(){

	    //String strs="{'手机京东':'京东', '优酷':'优酷视频', '手机百度':'百度', '蚂蜂窝旅游':'马蜂窝旅游','蚂蜂窝自由行':'马蜂窝旅游', '天猫':'手机天猫', '斗鱼':'斗鱼直播', '滴滴优步司机':'滴滴车主', '高德导航':'高德地图', '卡牛':'卡牛信用管家', '给你花':'给你花极速版', '极速钱包':'极速口袋钱包','王者荣耀助手':'王者荣耀皮肤助手','猫眼电影':'猫眼', '极速现金侠':'现金侠', '土豆':'土豆视频', '高铁管家':'高铁管家-12306火车票抢票','爱奇艺播放器':'爱奇艺', '银联钱包':'云闪付', '易到':'易到用车', '闪电借款领先版':'闪电借款', '车轮查违章':'车行易查违章', '前程无忧':'前程无忧51Job', '360云盘':'360安全云盘', '哈罗单车':'哈罗', '华住':'华住酒店', '随行付商务版':'随行付Plus','快贷贷款':'快贷', '搜房网房天下':'房天下', '卡牛信用卡管家':'卡牛信用管家', '东方财富网':'东方财富','嘀嗒拼车':'嘀嗒出行', '信用钱包-贷款易':'信用钱包', '花无缺借款':'花无缺', '企查查':'企查查企业信用查询','万能遥控':'万能遥控器', '聚美优品':'聚美', '闪银极速版':'闪银-贷款借钱', '财付通':'掌声财付通','手机贷-贷款借钱借款':'手机贷-贷款借钱借款', '我来贷个人版':'我来贷', '智行火车票':'智行火车票12306高铁抢票','51闪电贷':'闪电贷', '天眼查':'天眼查企业查询', '小赢卡贷升级版':'小赢卡贷', '搜狐新闻三星版':'搜狐新闻','苹果助手':'苹果查询助手', '功夫贷专业版':'功夫贷', '聚力体育':'聚力', '国美在线':'国美', '百度知道':'知道', '美团外卖商家':'美团外卖商家版', '格林豪泰':'格林', '金山词霸':'金山词霸练口语', '搜狐新闻曲屏版':'搜狐新闻','微车查违章':'微车违章查询', '享骑电单车':'享骑出行', '陌陌':'MOMO陌陌', '玖富万卡新手版':'玖富万卡', '拍拍贷借款(贷款·借钱·借贷)':'拍拍贷借款', '58同城网':'58同城', '平安一账通':'一账通', '闪贷-贷款借款分期':'闪贷','智行火车票12306购票':'智行火车票12306高铁抢票', '曹操专车':'曹操出行', '360摄像机':'360智能摄像机','货拉拉-搬家拉货':'货拉拉', '宜人贷借款极速版':'宜人贷借款', '企鹅直播':'企鹅体育-NBA直播','瑞银信':'瑞银商户', '百度外卖':'美团', '58速运':'58速运企业版', '虎扑体育':'虎扑足球', '聚力视频':'聚力短视频','车轮易查违章':'车行易查违章', '蚂蚁聚宝':'蚂蚁财富', '百度钱包':'度小满金融', '映客直播':'映客','爱彼迎':'Airbnb爱彼迎', '亲亲小贷':'亲亲小贷借款', '现金快贷':'现金快贷管家', '网易考拉海购':'网易考拉','平安天下通':'平安通', '天天中彩票':'天天中', '部落冲突':'部落冲突Clash-of-Clans', '皇室战争':'部落冲突:皇室战争', '天龙八部':'天龙八部手游', '狂野飙车8':'狂野飙车', '猎聘同道':'猎聘', '欢乐升级':'QQ欢乐升级', '宜人贷借款（信用卡极速贷款）':'宜人贷借款', '万达财富':'万达贷', '百度外卖-美食品质外卖':'美团','爱奇艺头条':'爱奇艺', '英雄杀':'英雄杀(官方版)', '豌豆荚':'豌豆荚安卓市场', '闪银借款':'闪银-贷款借钱','全民夺宝':'全民一元夺宝', '北京赛车':'北京赛车pk10','宜人贷':'宜人贷借款', '当当读书':'当当云阅读','贷款侠':'贷款侠借款', '联璧金融':'联璧','中石化加油卡掌上营业厅':'中国石化加油卡掌上营业厅','百度导航':'百度地图'}";
        String filePath="/Users/baiyx/Desktop/appNameMap.txt";

        Map<String, Float> data = new HashMap<String, Float>();
        CsvReader csvReader = null;
        try {
            String str= FileUtils.readFileToString(new File(filePath),"utf-8");
            JSONObject json= JSON.parseObject(str);

            int count=0;
            for(String key:json.keySet()){
                DictInfoDO entity=new DictInfoDO();
                entity.setCode(key);
                entity.setName(json.getString(key));
                entity.setType(DictInfoCode.DICT_APP_NAMEMAP_MODEL.getCode());

                entity.setId(UUID.randomUUID().toString().replace("-", ""));
                long status = dictInfoDao.insert(entity);
                count++;
                System.out.println("插入"+count+"条quan值计算");
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
	private void readRandomCsv2(){
		String filePath="/Users/baiyx/Desktop/AppModel_Quantile_190512.csv";
		Map<String, Float> data = new HashMap<String, Float>();
		CsvReader csvReader = null;
		try {
			char aa='a';
			FileInputStream inputStream=new FileInputStream(filePath);
			csvReader = new CsvReader(inputStream, Charset.defaultCharset());
			// 读表头
			csvReader.readHeaders();

			String[]headers=csvReader.getHeaders();
			// 读内容
			int count=0;
			while (csvReader.readRecord()) {
				String field=csvReader.get(0);
				for(int i=1;i<headers.length;i++){
                    String cat=headers[i];
                    String val= csvReader.get(i);

					DictInfoDO entity=new DictInfoDO();
					entity.setCode(cat+"_"+field);
					entity.setName(val);
					entity.setType(DictInfoCode.DICT_APP_QUAN_MODEL.getCode());

					entity.setId(UUID.randomUUID().toString().replace("-", ""));
					long status = dictInfoDao.insert(entity);
					count++;
					System.out.println("插入"+count+"条quan值计算");
                }

			}
			inputStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
	}

	public  void readRuleDict(){
		String filePath="/Users/baiyx/Desktop/ruleDict.csv";
		Map<String, Float> data = new HashMap<String, Float>();
		CsvReader csvReader = null;
		try {
			char aa='a';
			FileInputStream inputStream=new FileInputStream(filePath);
			csvReader = new CsvReader(inputStream, Charset.defaultCharset());
			// 读表头
			csvReader.readHeaders();

			String[]headers=csvReader.getHeaders();
			// 读内容
			int count=0;
			Map<String,List> ruleTypeMap=new HashMap<>();
			for(int i=2;i<headers.length;i++){
				ruleTypeMap.put(headers[i],new ArrayList());
			}
			while (csvReader.readRecord()) {
				String ruleId=csvReader.get(0);
				for(int i=1;i<headers.length;i++){
					String cat=headers[i];
					String val= csvReader.get(i);
					RuleInfoDo ruleInfoDo=new RuleInfoDo();
					if(i==1){
						String[] IdSegs=ruleId.replace("XIAOSHI","XIAO_SHI").
								replace("NETWORK","NET_WORK").split("_");
						if(IdSegs.length>1) {
							for (String seg : IdSegs) {
								val += (seg.charAt(0) + "").toUpperCase() + seg.substring(1).toLowerCase();
							}
							val = (val.charAt(0) + "").toLowerCase() + val.substring(1) + "Hit";
						}
						ruleInfoDo.setOutProp(val);

					}else {
						ruleInfoDo.setRiskLevel(val);
					}

					ruleTypeMap.get(headers[i]).add(ruleInfoDo);
					FileUtils.writeStringToFile(new File("/Users/baiyx/Desktop/ruleType.json"),JSON.toJSONString(ruleTypeMap));

//					DictInfoDO entity=new DictInfoDO();
//					entity.setCode(ruleId+"_"+cat);
//					entity.setName(val);
//					entity.setType(DictInfoCode.DICT_RUIE_INFO.getCode());
//
//					entity.setId(UUID.randomUUID().toString().replace("-", ""));
//					long status = dictInfoDao.insert(entity);
//					count++;
//					System.out.println("插入"+count+"条quan值计算");
				}

			}
			inputStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Transactional
	@Override
	public DictInfoResBO modifyDictInfo(DictInfoReqBO req) throws SysException{
	    DictInfoResBO res = new DictInfoResBO();
		try {
			DictInfoDO condition = CommonBeanConvertor.convert(req, DictInfoDO.class);
			long status = dictInfoDao.update(condition);
			if(status == 0) {
				res.setExCode(DictInfoExCode.SYS_NO_ENTITY_MODIFIED);
			} else {
				res.setExCode(DictInfoExCode.SUCCESS);
			}
		} catch (Exception e) {
			logger.error("Modify entity {} get into error", req, e);
			throw new SysException(DictInfoExCode.SYS_MODIFY_ENTITY_ERROR);
		} 
		return res;
	}

	@Transactional
	@Override
	public DictInfoResBO deleteDictInfo(DictInfoReqBO req) throws SysException{
	    DictInfoResBO res = new DictInfoResBO();
		
		try {
			DictInfoDO condition = CommonBeanConvertor.convert(req, DictInfoDO.class);
			long status = dictInfoDao.delete(condition);
			if(status == 0) {
				res.setExCode(DictInfoExCode.SYS_NO_ENTITY_DELETED);
			} else {
				res.setExCode(DictInfoExCode.SUCCESS);
			}
		} catch (Exception e) {
			logger.error("Delete entity {} get into error", req, e);
			throw new SysException(DictInfoExCode.SYS_DELETE_ENTITY_ERROR);
		}
		return res;
	}

	@Override
	public DictInfoResBO queryDictInfo(DictInfoReqBO req) throws SysException{
		DictInfoDO condition = CommonBeanConvertor.convert(req, DictInfoDO.class);
		DictInfoResBO res;
		
		try {
			List<DictInfoDO> entities = dictInfoDao.query(condition);
			res = CommonBeanConvertor.convert(entities, DictInfoResBO.class, DictInfoBeanBO.class);
		} catch(Exception e) {
			logger.error("Query entity {} get into error", req, e);
			throw new SysException(DictInfoExCode.SYS_QUERY_ENTITY_ERROR);
		}
		return res;
	}

	@Override
	public Object getDictInfo(String code, String type) throws SysException {
		try{

			return redisUtil.get(AlarmInfoCode.REDIS_GENERAL_DICT.getCode()+"_"+type+"_"+code);

		}catch (Exception ex){
			logger.error("Query dict {} get into error", type+"_"+code, ex);
			throw new SysException(DictInfoExCode.SYS_GET_REIDS_ERRO);
		}

	}
	@Override
	public List<Object> getMuitleDictInfo(List<String> codes, String type) throws SysException {
		try{

			List arr=new ArrayList();
			for(String key:codes){
				arr.add(AlarmInfoCode.REDIS_GENERAL_DICT.getCode()+"_"+type+"_"+key);
			}
			return  redisUtil.multiGet(arr);

		}catch (Exception ex){
			logger.error("Query dict {} get into error", type+"_"+codes, ex);
			throw new SysException(DictInfoExCode.SYS_GET_REIDS_ERRO);
		}

	}

//	public  boolean setIfAbsent(final String key, final Serializable value, final long exptime) {
//		Boolean b = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
//			@Override
//			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
//				RedisSerializer valueSerializer = redisTemplate.getValueSerializer();
//				RedisSerializer keySerializer = redisTemplate.getKeySerializer();
////				Object obj = connection.execute("set", keySerializer.serialize(key),
////						valueSerializer.serialize(value),
////						//SafeEncoder.encode("NX"),
////						//SafeEncoder.encode("EX"),
////						//Protocol.toByexptime));
//
//				//return obj != null;
//				return false;
//			}
//		});
//		return b;
//	}
	@Autowired
	SqlSessionTemplate sqlSessionTemplate;

	public void loadGeneralDict() throws SysException {
		logger.info("开始加载通用字典数据到 redis");
		try{
			//readRandomCsv1();
			//readRandomCsv2();
            //readAppNameMap();
			//readRuleDict();
			final Map<String,Object> map=new HashMap<>();
			final int[] total={0};

			sqlSessionTemplate.select("com.handydata.antifraud.entity.DictInfoDO.query", new ResultHandler<DictInfoDO>() {

				int count=0;
				int batchSize=500;
				@Override
				public void handleResult(ResultContext<? extends DictInfoDO> resultContext) {
					DictInfoDO entity=null;
					try {
						entity=resultContext.getResultObject();
						map.put(AlarmInfoCode.REDIS_GENERAL_DICT.getCode() + "_" + entity.getType() + "_" + entity.getCode(), entity.getName());
						count++;
						if(count==batchSize){
							redisUtil.batchSet(map);
							map.clear();
							total[0]+=count;
							logger.info("已加载"+total[0]+"条数据到redis");
							count=0;

						}
					}catch (Exception ex){
						logger.error("加载该条字典到缓存失败{}",entity.getId(),ex);

					}

				}
			});
			total[0]+=map.size();
			redisUtil.batchSet(map);
			logger.info("加载"+map.size()+"条数据到redis,共加载"+total[0]+"条数据，完成加载");


		}catch (Exception ex){

			logger.error("加字典信息到缓存失败{}",ex);

			throw new SysException(DictInfoExCode.SYS_PUT_REIDS_ERRO);
		}


	}

}
